package com.lfy.conf;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lfy.domian.ErrorMqEntity;
import com.lfy.domian.User;
import com.lfy.event.EventLfyEntity;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

@Configuration
public class SendConf  {
    @Resource
    RabbitTemplate rabbitTemplate;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    RedisTemplate redisTemplate;
    @Bean
    public MessageConverter messageConverter(){
        //jdk自带序列化json
        return new Jackson2JsonMessageConverter();
    }

    @PostConstruct //RabbitConfig 对象创建完成后，执行这个方法
    public void initRabbitTemplate() {
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {

            //服务器发送者==》交换机
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                // CorrelationData 当前消息唯一id
                // ack 消息是否成功收到
                // cause 失败的原因
                if(ack){
                    System.out.println(correlationData);
                    System.out.println("是否成功收到："+ack);
                    System.out.println("失败的原因："+cause);
                    System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++");

                }
            }
        });

        //如果交换机发送给队列发生错误，进入此方法错误回调
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @SneakyThrows
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {

//                rabbitTemplate.convertAndSend(exchange,routingKey,message);
                // message:投递失败的消息详细信息
                // replyCode：回复的状态码
                // replyText：回复的文本内容
                // exchange：当时这个消息发送给哪个交换机
                //routingKey：当时这个消息用的什么路由键
                Integer sum =(Integer) redisTemplate.opsForValue().get("Tag:" + message.getMessageProperties().getDeliveryTag());
                System.out.println("第几次"+sum);
                if(sum == null){
                    redisTemplate.opsForValue().set("Tag:"+message.getMessageProperties().getDeliveryTag(),1);
                } else if(sum >= 3){
                    ErrorMqEntity errorMqEntity = new ErrorMqEntity();
                    errorMqEntity.setRouteKey(routingKey);
                    errorMqEntity.setB(exchange);
                    errorMqEntity.setObject(message);
                    ObjectMapper objectMapper = new ObjectMapper();
                    String s = objectMapper.writeValueAsString(errorMqEntity);
                    objectMapper.readValue(s.getBytes(StandardCharsets.UTF_8), new TypeReference<EventLfyEntity>() {
                    });
                    stringRedisTemplate.opsForValue().set("ErrorNew",s);
                    return;
                } else {
                    redisTemplate.opsForValue().increment("Tag:"+message.getMessageProperties().getDeliveryTag());
                }


                rabbitTemplate.convertAndSend(exchange,routingKey,message);
                System.out.println(message);
                System.out.println("==========================");
                System.out.println(message.getBody());
                ObjectMapper objectMapper = new ObjectMapper();
                try {
                    User user = objectMapper.readValue(message.getBody(), new TypeReference<User>() {
                    });
                    System.out.println(user);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                message.getMessageProperties().getHeaders().get("");
                System.out.println("==========================");
                System.out.println(replyText);
                System.out.println(Arrays.toString(message.getBody()));
                System.out.println(message.getMessageProperties());
                System.out.println(exchange);
                System.out.println(routingKey);
                System.out.println("+++++++++++++++++++++++++++++++++++++++++");
            }
        });


    }


}
